_require "../../../../basis.smi"
_require local "../../../../config/main/Version.smi"
_require local "../../../libs/config/main/Config.smi"
_require local "../../../data/symbols/main/Loc.smi"
_require local "../../../extensions/debug/main/Bug.smi"
(* _require local "../../../libs/env/main/SEnv.smi" *)
(* _require local "../../../libs/env/main/SSet.smi" *)

_require local "../../../data/control/main/Control.smi"
_require local "../../../libs/util/main/Counter.smi"
_require local "../../../extensions/usererror/main/UserError.ppg.smi"
_require local "../../../extensions/userlevelprimitive/main/UserLevelPrimitive.smi"
_require "../../../libs/toolchain/main/Filename.smi"
_require local "../../../libs/toolchain/main/CoreUtils.smi"
_require "../../../libs/toolchain/main/ShellUtils.smi"
_require local "../../../libs/toolchain/main/TempFile.smi"
_require local "../../../libs/toolchain/main/BinUtils.smi"
_require local "../../../compilePhases/parser/main/Parser.smi"
_require local "./GetOptLong.smi"
_require local "./RunLoop.smi"
_require local "./ExecutablePath.smi"
_require "../../../libs/toolchain/main/LLVMUtils.smi"
_require "../../../compilerIRs/absyn/main/InterfaceName.ppg.smi"
_require "../../../compilePhases/toplevel/main/Top.smi"
_require local "../../../compilePhases/loadfile/main/LoadFile.smi"
_require local "../../../compilePhases/analyzefiles/main/AnalyzeFiles.smi"
_require local "../../../compilePhases/nameevaluation/main/NameEvalEnvPrims.smi"
_require local "./SignalHandler.smi"
_require "./UserFileMap.smi"
(* _require local "./MainUtils.smi" *)

structure Main =
struct

(* 以下は、make testで使用 *)
  datatype file_place_limit =
      ALL_PLACE
    | USERPATH_ONLY

  val loadConfig
      : ['a#{systemBaseDir : Filename.filename}. 'a -> unit]

  val loadBuiltin
      : ['a#{systemBaseDir : Filename.filename}. 'a -> Top.toplevelContext]

  val loadPrelude
      : ['a#{linkOptions : 'b,
             topContext : unit -> Top.toplevelContext,
             topOptions : 'c,
             require : Filename.filename list},
         'b#{systemBaseDir : Filename.filename},
         'c#{loadPath : InterfaceName.source list}.
         'a -> InterfaceName.file_dependency * Top.toplevelContext]
  val makeLLVMOptions
      : ['a#{systemBaseExecDir : Filename.filename,
             triple : string option,
             arch : string,
             cpu : string,
             features : string,
             optLevel : LLVMUtils.opt_level,
             relocModel : LLVMUtils.reloc_model option,
             LLCFLAGS : ShellUtils.arg list,
             OPTFLAGS : ShellUtils.arg list}.
         'a -> LLVMUtils.compile_options]

  val compileSMLFile
      : ['a#{llvmOptions : LLVMUtils.compile_options,
             topOptions : Top.options,
             topContext : unit -> Top.toplevelContext,
             fileMap : (unit -> UserFileMap.map) option}.
         'a
         -> {outputFileType : LLVMUtils.file_type,
             outputFilename : Filename.filename option}
         -> Filename.filename
         -> InterfaceName.file_dependency]

  val link
      : ['a#{llvmOptions : LLVMUtils.compile_options,
             topOptions : Top.options,
             topContext : unit -> Top.toplevelContext,
             linkOptions : 'b,
             fileMap : (unit -> UserFileMap.map) option},
         'b#{systemBaseDir : Filename.filename,
             LDFLAGS : ShellUtils.arg list,
             LIBS : ShellUtils.arg list,
             noStdLib : bool,
             useCXX : bool}.
         'a
         -> {sourceFiles : Filename.filename list,
             outputFile : Filename.filename}
         -> InterfaceName.file_dependency list]

  val printDependCompile
      : ['a#{llvmOptions : LLVMUtils.compile_options,
             topOptions : Top.options,
             topContext : unit -> Top.toplevelContext,
             fileMap : (unit -> UserFileMap.map) option}.
         'a
	 -> {limit : file_place_limit, out : string -> unit}
         -> Filename.filename
         -> unit]

  val printDependLink
      : ['a#{generateMakefileOptions : 'b,
             llvmOptions : LLVMUtils.compile_options,
             topOptions : Top.options,
             topContext : unit -> Top.toplevelContext,
             fileMap : (unit -> UserFileMap.map) option},
         'b#{limit : file_place_limit}.
         'a
	 -> {limit : file_place_limit, out : string -> unit}
         -> Filename.filename
         -> unit]

  val generateMakefile
      : ['a#{generateMakefileOptions : 'b,
             llvmOptions : LLVMUtils.compile_options,
             topOptions : Top.options,
             topContext : unit -> Top.toplevelContext,
             fileMap : (unit -> UserFileMap.map) option},
         'b#{programName : string,
             systemBaseDir : Filename.filename,
             systemBaseDirSpecified : bool,
             systemBaseExecDir : Filename.filename,
             systemBaseExecDirSpecified : bool}.
         'a
	 -> {limit : file_place_limit, out : string -> unit}
         -> Filename.filename list
         -> unit]

  val command : string * string list -> unit

  val printExn : string -> exn -> unit
(* 以上は、make testで使用 *)

  val main : string * string list -> OS.Process.status


end
